}
}
+void
+gtk_css_shadows_value_snapshot_outset (const GtkCssValue *shadows,
+ GtkSnapshot *snapshot,
+ const GtkRoundedBox *border_box)
+{
+ guint i;
+
+ g_return_if_fail (shadows->class == >K_CSS_VALUE_SHADOWS);
+
+ for (i = 0; i < shadows->len; i++)
+ {
+ if (_gtk_css_shadow_value_get_inset (shadows->values[i]))
+ continue;
+
+ gtk_css_shadow_value_snapshot_outset (shadows->values[i], snapshot, border_box);
+ }
+}
+
+void
+gtk_css_shadows_value_snapshot_inset (const GtkCssValue *shadows,
+ GtkSnapshot *snapshot,
+ const GtkRoundedBox *padding_box)
+{
+ guint i;
+
+ g_return_if_fail (shadows->class == >K_CSS_VALUE_SHADOWS);
+
+ for (i = 0; i < shadows->len; i++)
+ {
+ if (!_gtk_css_shadow_value_get_inset (shadows->values[i]))
+ continue;
+
+ gtk_css_shadow_value_snapshot_inset (shadows->values[i], snapshot, padding_box);
+ }
+}
+
void
_gtk_css_shadows_value_get_extents (const GtkCssValue *shadows,
GtkBorder *border)
cairo_t *cr,
const GtkRoundedBox *padding_box,
gboolean inset);
+void gtk_css_shadows_value_snapshot_outset (const GtkCssValue *shadows,
+ GtkSnapshot *snapshot,
+ const GtkRoundedBox *border_box);
+void gtk_css_shadows_value_snapshot_inset (const GtkCssValue *shadows,
+ GtkSnapshot *snapshot,
+ const GtkRoundedBox *padding_box);
void _gtk_css_shadows_value_get_extents (const GtkCssValue *shadows,
GtkBorder *border);
#include "gtkcsscolorvalueprivate.h"
#include "gtkcssnumbervalueprivate.h"
#include "gtkcssrgbavalueprivate.h"
+#include "gtksnapshot.h"
#include "gtkstylecontextprivate.h"
#include "gtkrenderprivate.h"
#include "gtkpango.h"
cairo_restore (cr);
}
+
+void
+gtk_css_shadow_value_snapshot_outset (const GtkCssValue *shadow,
+ GtkSnapshot *snapshot,
+ const GtkRoundedBox *border_box)
+{
+ GtkBorder extents;
+ cairo_t *cr;
+
+ g_return_if_fail (shadow->class == >K_CSS_VALUE_SHADOW);
+
+ /* We don't need to draw invisible shadows */
+ if (gtk_rgba_is_clear (_gtk_css_rgba_value_get_rgba (shadow->color)))
+ return;
+
+ gtk_css_shadow_value_get_extents (shadow, &extents);
+
+ cr = gtk_snapshot_append_cairo_node (snapshot,
+ &(graphene_rect_t) GRAPHENE_RECT_INIT (
+ border_box->box.x - extents.left,
+ border_box->box.y - extents.top,
+ border_box->box.width + extents.left + extents.right,
+ border_box->box.height + extents.top + extents.bottom),
+ "Outset Shadow");
+ _gtk_css_shadow_value_paint_box (shadow, cr, border_box);
+ cairo_destroy (cr);
+}
+
+void
+gtk_css_shadow_value_snapshot_inset (const GtkCssValue *shadow,
+ GtkSnapshot *snapshot,
+ const GtkRoundedBox *padding_box)
+{
+ cairo_t *cr;
+
+ g_return_if_fail (shadow->class == >K_CSS_VALUE_SHADOW);
+
+ /* We don't need to draw invisible shadows */
+ if (gtk_rgba_is_clear (_gtk_css_rgba_value_get_rgba (shadow->color)))
+ return;
+
+ cr = gtk_snapshot_append_cairo_node (snapshot,
+ &(graphene_rect_t) GRAPHENE_RECT_INIT (
+ padding_box->box.x,
+ padding_box->box.y,
+ padding_box->box.width,
+ padding_box->box.height),
+ "Inset Shadow");
+ _gtk_css_shadow_value_paint_box (shadow, cr, padding_box);
+ cairo_destroy (cr);
+}
+
void _gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow,
cairo_t *cr);
-
void _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow,
cairo_t *cr,
const GtkRoundedBox *padding_box);
+void gtk_css_shadow_value_snapshot_outset (const GtkCssValue *shadow,
+ GtkSnapshot *snapshot,
+ const GtkRoundedBox *border_box);
+void gtk_css_shadow_value_snapshot_inset (const GtkCssValue *shadow,
+ GtkSnapshot *snapshot,
+ const GtkRoundedBox *padding_box);
+
G_END_DECLS
#endif /* __GTK_SHADOW_H__ */
}
static void
-_gtk_theming_background_init_style (GtkThemingBackground *bg,
- double width,
- double height,
- GtkJunctionSides junction)
+gtk_theming_background_init (GtkThemingBackground *bg,
+ GtkCssStyle *style,
+ double width,
+ double height,
+ GtkJunctionSides junction)
{
GtkBorder border, padding;
+ bg->style = style;
+
border.top = _gtk_css_number_value_get (gtk_css_style_get_value (bg->style, GTK_CSS_PROPERTY_BORDER_TOP_WIDTH), 100);
border.right = _gtk_css_number_value_get (gtk_css_style_get_value (bg->style, GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH), 100);
border.bottom = _gtk_css_number_value_get (gtk_css_style_get_value (bg->style, GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH), 100);
_gtk_css_shadows_value_is_none (box_shadow))
return;
- bg.style = style;
- _gtk_theming_background_init_style (&bg, width, height, junction);
+ gtk_theming_background_init (&bg, style, width, height, junction);
cairo_save (cr);
cairo_translate (cr, x, y);
gdouble height,
GtkJunctionSides junction)
{
+ GtkThemingBackground bg;
+ gint idx;
GtkCssValue *background_image;
+ GtkCssValue *blend_modes;
GtkCssValue *box_shadow;
const GdkRGBA *bg_color;
- GtkBorder shadow;
- graphene_rect_t bounds;
+ gint number_of_layers;
cairo_t *cr;
background_image = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BACKGROUND_IMAGE);
+ blend_modes = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BACKGROUND_BLEND_MODE);
bg_color = _gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BACKGROUND_COLOR));
box_shadow = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BOX_SHADOW);
_gtk_css_shadows_value_is_none (box_shadow))
return;
- _gtk_css_shadows_value_get_extents (box_shadow, &shadow);
+ gtk_theming_background_init (&bg, style, width, height, junction);
- graphene_rect_init (&bounds,
- - shadow.left,
- - shadow.top,
- ceil (width) + shadow.left + shadow.right,
- ceil (height) + shadow.top + shadow.bottom);
+ gtk_css_shadows_value_snapshot_outset (box_shadow,
+ snapshot,
+ &bg.boxes[GTK_CSS_AREA_BORDER_BOX]);
+ /*
+ * When we have a blend mode set for the background, we must blend on a transparent
+ * background. GSK can't do that yet.
+ */
cr = gtk_snapshot_append_cairo_node (snapshot,
- &bounds,
- "Background");
+ &(graphene_rect_t)GRAPHENE_RECT_INIT(0, 0, width, height),
+ "Background with blend mode");
- gtk_css_style_render_background (style, cr, 0, 0, width, height, junction);
+ _gtk_theming_background_paint_color (&bg, cr, bg_color, background_image);
+
+ number_of_layers = _gtk_css_array_value_get_n_values (background_image);
+
+ for (idx = number_of_layers - 1; idx >= 0; idx--)
+ {
+ GtkCssBlendMode blend_mode;
+
+ blend_mode = _gtk_css_blend_mode_value_get (_gtk_css_array_value_get_nth (blend_modes, idx));
+
+ _gtk_theming_background_paint_layer (&bg, idx, cr, blend_mode);
+ }
cairo_destroy (cr);
+
+ gtk_css_shadows_value_snapshot_inset (box_shadow,
+ snapshot,
+ &bg.boxes[GTK_CSS_AREA_PADDING_BOX]);
}